//Tripilller, all rights reserved.

package gui;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextPane;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.LayoutStyle;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableModel;
import javax.swing.text.AbstractDocument;
import javax.swing.text.BoxView;
import javax.swing.text.ComponentView;
import javax.swing.text.Element;
import javax.swing.text.IconView;
import javax.swing.text.LabelView;
import javax.swing.text.ParagraphView;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledEditorKit;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
import javax.swing.tree.DefaultMutableTreeNode;

import utility.GlowwormDumpVisitor;
import utility.SymbolTable;

public class MainFrame extends JFrame {

	private static final long serialVersionUID = 7706164050997096978L;

	public MainFrame() {
		initComponents();
	}

	private void initComponents() {

		jSplitPaneHorizontal = new JSplitPane();
		jSplitPaneVertical = new JSplitPane();
		jInternalFrameEditor = new JInternalFrame();
		jTabbedPaneEditor = new JTabbedPane();
		jTextPaneEditor = new JTextPane();
		jInternalFrameProblem = new JInternalFrame();
		jTabbedPaneProblems = new JTabbedPane();
		jScrollPaneProblems = new JScrollPane();
		jTableProblems = new JTable();
		jInternalFrameAnalysis = new JInternalFrame();
		jTabbedPaneAnalysis = new JTabbedPane();
		jScrollPaneLexical = new JScrollPane();
		jTableLexical = new JTable();
		jScrollPaneSyntax = new JScrollPane();
		jTreeSyntax = new JTree();
		jScrollPaneSemantics = new JScrollPane();
		jTableSemantics = new JTable();
		jScrollPaneAssembly = new JScrollPane();
		jTextPaneAssembly = new JTextPane();
		jFileChooser1 = new JFileChooser();
		jMenuBar1 = new JMenuBar();
		jMenuFile = new JMenu();
		jMenuItemOpen = new JMenuItem();
		jMenuItemSaveAs = new JMenuItem();
		jMenuEdit = new JMenu();
		jMenuItemUndo = new JMenuItem();
		jMenuItemRedo = new JMenuItem();
		jMenuCompile = new JMenu();
		jMenuItemCompile = new JMenuItem();
		jMenuType = new JMenu();
		jCheckBoxMenuItemLexical = new JCheckBoxMenuItem();
		jCheckBoxMenuItemSyntax = new JCheckBoxMenuItem();
		jCheckBoxMenuItemSemantics = new JCheckBoxMenuItem();
		jCheckBoxMenuItemAssembly = new JCheckBoxMenuItem();
		jButtonCompile = new JButton();
		jToolBar1 = new JToolBar();

		jTextPaneEditor.setEditorKit(new NumberedEditorKit());
		jTextPaneEditor.getDocument().addDocumentListener(
				new SyntaxHighlighter(jTextPaneEditor));
		jScrollPaneEditor = new JScrollPane(jTextPaneEditor);

		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		setTitle("Tripilller");
		setPreferredSize(new Dimension(1280, 720));

		jSplitPaneHorizontal.setDividerLocation(900);
		jSplitPaneHorizontal.setFont(new Font("Segoe UI", 0, 17)); // NOI18N

		jSplitPaneVertical.setDividerLocation(450);
		jSplitPaneVertical.setOrientation(JSplitPane.VERTICAL_SPLIT);

		jInternalFrameEditor.setBorder(BorderFactory.createEtchedBorder());
		jInternalFrameEditor.setClosable(true);
		jInternalFrameEditor.setTitle("Editor");
		jInternalFrameEditor.setVisible(true);

		jTabbedPaneEditor.addTab("New File", jScrollPaneEditor);

		GroupLayout jInternalFrameEditorLayout = new GroupLayout(
				jInternalFrameEditor.getContentPane());
		jInternalFrameEditor.getContentPane().setLayout(
				jInternalFrameEditorLayout);
		jInternalFrameEditorLayout
				.setHorizontalGroup(jInternalFrameEditorLayout
						.createParallelGroup(GroupLayout.Alignment.LEADING)
						.addComponent(jTabbedPaneEditor,
								GroupLayout.Alignment.TRAILING,
								GroupLayout.DEFAULT_SIZE, 943, Short.MAX_VALUE));
		jInternalFrameEditorLayout.setVerticalGroup(jInternalFrameEditorLayout
				.createParallelGroup(GroupLayout.Alignment.LEADING)
				.addComponent(jTabbedPaneEditor, GroupLayout.DEFAULT_SIZE, 416,
						Short.MAX_VALUE));

		jSplitPaneVertical.setTopComponent(jInternalFrameEditor);

		jInternalFrameProblem.setBorder(BorderFactory.createEtchedBorder());
		jInternalFrameProblem.setClosable(true);
		jInternalFrameProblem.setTitle("Problems");
		jInternalFrameProblem.setVisible(true);

		jTableProblems.setFont(new Font("Segoe UI", 0, 17)); // NOI18N
		jTableProblems.setModel(new DefaultTableModel(new Object[][] {},
				new String[] { "Description", "Line", "Column", "Type" }));
		jScrollPaneProblems.setViewportView(jTableProblems);

		jTabbedPaneProblems.addTab("Problems", jScrollPaneProblems);

		GroupLayout jInternalFrameProblemLayout = new GroupLayout(
				jInternalFrameProblem.getContentPane());
		jInternalFrameProblem.getContentPane().setLayout(
				jInternalFrameProblemLayout);
		jInternalFrameProblemLayout
				.setHorizontalGroup(jInternalFrameProblemLayout
						.createParallelGroup(GroupLayout.Alignment.LEADING)
						.addComponent(jTabbedPaneProblems,
								GroupLayout.Alignment.TRAILING,
								GroupLayout.DEFAULT_SIZE, 943, Short.MAX_VALUE));
		jInternalFrameProblemLayout
				.setVerticalGroup(jInternalFrameProblemLayout
						.createParallelGroup(GroupLayout.Alignment.LEADING)
						.addComponent(jTabbedPaneProblems,
								GroupLayout.Alignment.TRAILING,
								GroupLayout.DEFAULT_SIZE, 203, Short.MAX_VALUE));

		jSplitPaneVertical.setRightComponent(jInternalFrameProblem);

		jSplitPaneHorizontal.setLeftComponent(jSplitPaneVertical);

		jInternalFrameAnalysis.setBorder(BorderFactory.createEtchedBorder());
		jInternalFrameAnalysis.setClosable(true);
		jInternalFrameAnalysis.setTitle("Analysis");
		jInternalFrameAnalysis.setVisible(true);

		jScrollPaneEditor.setFont(new Font("Segoe UI", 0, 13)); // NOI18N
		jTableLexical.setFont(new Font("Segoe UI", 0, 13)); // NOI18N
		jTableLexical.setModel(new DefaultTableModel(new Object[][] {},
				new String[] { "Type", "Code" }));
		jScrollPaneLexical.setViewportView(jTableLexical);

		jTabbedPaneAnalysis.addTab("Lexical", jScrollPaneLexical);

		jTreeSyntax.setFont(new Font("Segoe UI", 0, 13)); // NOI18N

		jTabbedPaneAnalysis.addTab("Syntax", jScrollPaneSyntax);

		jTableSemantics.setFont(new Font("Segoe UI", 0, 13)); // NOI18N
		jTableSemantics.setModel(new DefaultTableModel(new Object[][] {},
				new String[] { "Variable", "Type", "Line", "Column" }));
		jScrollPaneSemantics.setViewportView(jTableSemantics);

		jTabbedPaneAnalysis.addTab("Semantics", jScrollPaneSemantics);

		jTextPaneAssembly.setEditable(false);
		jTextPaneAssembly.setFont(new Font("Segoe UI", 0, 13)); // NOI18N
		jScrollPaneAssembly.setViewportView(jTextPaneAssembly);

		jTabbedPaneAnalysis.addTab("Assembly", jScrollPaneAssembly);

		GroupLayout jInternalFrameAnalysisLayout = new GroupLayout(
				jInternalFrameAnalysis.getContentPane());
		jInternalFrameAnalysis.getContentPane().setLayout(
				jInternalFrameAnalysisLayout);
		jInternalFrameAnalysisLayout
				.setHorizontalGroup(jInternalFrameAnalysisLayout
						.createParallelGroup(GroupLayout.Alignment.LEADING)
						.addComponent(jTabbedPaneAnalysis,
								GroupLayout.Alignment.TRAILING,
								GroupLayout.DEFAULT_SIZE, 320, Short.MAX_VALUE));
		jInternalFrameAnalysisLayout
				.setVerticalGroup(jInternalFrameAnalysisLayout
						.createParallelGroup(GroupLayout.Alignment.LEADING)
						.addComponent(jTabbedPaneAnalysis,
								GroupLayout.DEFAULT_SIZE, 659, Short.MAX_VALUE));

		jSplitPaneHorizontal.setRightComponent(jInternalFrameAnalysis);

		jFileChooser1.setFont(new Font("Segoe UI", 0, 13)); // NOI18N
		jFileChooser1.setEnabled(false);

		jToolBar1.setRollover(true);
		jToolBar1.setFloatable(false);

		jButtonCompile.setFont(new Font("Segoe UI", 0, 13)); // NOI18N
		jButtonCompile.setText("Compile");
		jButtonCompile.setFocusable(false);
		jButtonCompile.setHorizontalTextPosition(SwingConstants.CENTER);
		jButtonCompile.setVerticalTextPosition(SwingConstants.BOTTOM);
		jButtonCompile.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				jMenuItemCompileActionPerformed(evt);
			}
		});
		jToolBar1.add(jButtonCompile);

		jMenuFile.setText("File");

		jMenuItemOpen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,
				InputEvent.CTRL_MASK));
		jMenuItemOpen.setText("Open");
		jMenuItemOpen.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				jMenuItemOpenActionPerformed(evt);
			}
		});
		jMenuFile.add(jMenuItemOpen);

		jMenuItemSaveAs.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
				InputEvent.CTRL_MASK));
		jMenuItemSaveAs.setText("Save As");
		jMenuItemSaveAs.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				jMenuItemSaveAsActionPerformed(evt);
			}
		});
		jMenuFile.add(jMenuItemSaveAs);

		jMenuBar1.add(jMenuFile);

		jMenuEdit.setText("Edit");

		jMenuItemUndo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z,
				InputEvent.CTRL_MASK));
		jMenuItemUndo.setText("Undo");
		jMenuEdit.add(jMenuItemUndo);

		jMenuItemRedo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y,
				InputEvent.CTRL_MASK));
		jMenuItemRedo.setText("Redo");
		jMenuEdit.add(jMenuItemRedo);

		jMenuBar1.add(jMenuEdit);

		jMenuCompile.setText("Compile");

		jMenuItemCompile.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F5,
				0));
		jMenuItemCompile.setText("Compile");
		jMenuItemCompile.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				jMenuItemCompileActionPerformed(evt);
			}
		});
		jMenuCompile.add(jMenuItemCompile);

		jMenuType.setText("Compile Type");

		jCheckBoxMenuItemLexical.setSelected(true);
		jCheckBoxMenuItemLexical.setText("Lexical Analysis");
		jMenuType.add(jCheckBoxMenuItemLexical);

		jCheckBoxMenuItemSyntax.setSelected(true);
		jCheckBoxMenuItemSyntax.setText("Syntax Analysis");
		jMenuType.add(jCheckBoxMenuItemSyntax);

		jCheckBoxMenuItemSemantics.setSelected(true);
		jCheckBoxMenuItemSemantics.setText("Semantics Analysis");
		jMenuType.add(jCheckBoxMenuItemSemantics);

		jCheckBoxMenuItemAssembly.setSelected(true);
		jCheckBoxMenuItemAssembly.setText("Assembly Geneartion");
		jMenuType.add(jCheckBoxMenuItemAssembly);

		jMenuCompile.add(jMenuType);

		jMenuBar1.add(jMenuCompile);

		setJMenuBar(jMenuBar1);

		GroupLayout layout = new GroupLayout(getContentPane());
		getContentPane().setLayout(layout);
		layout.setHorizontalGroup(layout
				.createParallelGroup(GroupLayout.Alignment.LEADING)
				.addComponent(jSplitPaneHorizontal,
						GroupLayout.Alignment.TRAILING)
				.addComponent(jToolBar1, GroupLayout.DEFAULT_SIZE,
						GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
				.addGroup(
						layout.createParallelGroup(
								GroupLayout.Alignment.LEADING).addGroup(
								layout.createSequentialGroup()
										.addGap(0, 288, Short.MAX_VALUE)
										.addGap(0, 288, Short.MAX_VALUE))));
		layout.setVerticalGroup(layout
				.createParallelGroup(GroupLayout.Alignment.LEADING)
				.addGroup(
						GroupLayout.Alignment.TRAILING,
						layout.createSequentialGroup()
								.addComponent(jToolBar1,
										GroupLayout.PREFERRED_SIZE, 25,
										GroupLayout.PREFERRED_SIZE)
								.addPreferredGap(
										LayoutStyle.ComponentPlacement.RELATED)
								.addComponent(jSplitPaneHorizontal,
										GroupLayout.DEFAULT_SIZE, 662,
										Short.MAX_VALUE))
				.addGroup(
						layout.createParallelGroup(
								GroupLayout.Alignment.LEADING).addGroup(
								layout.createSequentialGroup()
										.addGap(0, 149, Short.MAX_VALUE)
										.addGap(0, 149, Short.MAX_VALUE))));
		pack();
	}

	private void jMenuItemOpenActionPerformed(ActionEvent evt) {
		int returnVal = jFileChooser1.showOpenDialog(this);
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File file = jFileChooser1.getSelectedFile();
			try {
				jTextPaneEditor.read(new FileReader(file.getAbsolutePath()),
						null);
			} catch (IOException ex) {
				System.out.println("problem accessing file"
						+ file.getAbsolutePath());
			}
		}
	}

	private void jMenuItemSaveAsActionPerformed(ActionEvent evt) {
		int returnVal = jFileChooser1.showOpenDialog(this);
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File file = jFileChooser1.getSelectedFile();
			try {
				FileOutputStream fos = new FileOutputStream(new File(
						file.getAbsolutePath()));
				OutputStreamWriter osw = new OutputStreamWriter(fos);
				String saveString = jTextPaneEditor.getText().replaceAll("\n",
						"\r\n");
				osw.write(saveString);
				osw.flush();
				osw.close();
			} catch (IOException ex) {
				System.out.println("problem accessing file"
						+ file.getAbsolutePath());
			}
		}
	}

	private void jMenuItemCompileActionPerformed(ActionEvent evt) {
		String toDeal = jTextPaneEditor.getText();
		StringReader reader = new StringReader(toDeal);
		parser.ReInit(reader);
		String content = "";
		boolean doLexical = jCheckBoxMenuItemLexical.getState();
		boolean doSemantics = jCheckBoxMenuItemSemantics.getState();
		boolean doSyntax = jCheckBoxMenuItemSyntax.getState();
		boolean doAssembly = jCheckBoxMenuItemAssembly.getState();
		String[] intoLine;
		DefaultTableModel model = (DefaultTableModel) jTableProblems.getModel();
		for (; model.getRowCount() > 0;) {
			model.removeRow(0);
		}

		if (doLexical) {
			try {
				model = (DefaultTableModel) jTableProblems.getModel();
				for (; model.getRowCount() > 0;) {
					model.removeRow(0);
				}
				content = Glowworm.lex();
				intoLine = content.split("\n");
				for (int i = 0; i < intoLine.length; i++) {
					int colonPosition = intoLine[i].indexOf(":");
					if (colonPosition != -1) {
						String type = intoLine[i].substring(1,
								colonPosition - 1);
						String code = intoLine[i].substring(colonPosition + 1);
						type = type.substring(1);
						code = code.substring(1);
						model = (DefaultTableModel) jTableLexical.getModel();
						model.addRow(new Object[] { type, code });
					}
				}

			} catch (TokenMgrError e) {
				content = e.getMessage();
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}

		if (doSyntax) {
			try {
				SimpleNode n = Glowworm.program();
				content = n.dump("");
				intoLine = content.split("\n");
				int lastLevel = -1;
				int level;
				String type;
				DefaultMutableTreeNode node;
				Vector<DefaultMutableTreeNode> vectorNode = new Vector<DefaultMutableTreeNode>();
				for (int i = 0; i < intoLine.length; i++) {

					level = 0;
					for (; intoLine[i].substring(0, 1).equals("-"); level++) {
						intoLine[i] = intoLine[i].substring(1);
					}
					if (intoLine[i].substring(0, 1).equals("_")) {
						intoLine[i] = intoLine[i].substring(1);
					}

					type = getType(intoLine[i]);
					if (matchSymbol(type)) {
						continue;
					}
					node = new DefaultMutableTreeNode(intoLine[i]);

					if (level == 0) {
						vectorNode.add(node);
						jTreeSyntax = new JTree(node);
					} else if (level - lastLevel == 1) {
						vectorNode.get(vectorNode.size() - 2).add(node);
						vectorNode.remove(vectorNode.size() - 1);
						vectorNode.add(node);
					} else if (level > lastLevel) {
						lastLevel++;
						vectorNode.get(vectorNode.size() - 1).add(node);
						vectorNode.add(node);
					} else if (level <= lastLevel) {
						int i1;
						for (i1 = 0; i1 <= lastLevel - level; i1++) {
							vectorNode.remove(vectorNode.size() - 1);
						}
						lastLevel -= i1;
						vectorNode.get(vectorNode.size() - 2).add(node);
						vectorNode.remove(vectorNode.size() - 1);
						vectorNode.add(node);
					}
				}
				jScrollPaneSyntax.setViewportView(jTreeSyntax);

				if (doSemantics) {
					GlowwormDumpVisitor gdv = new GlowwormDumpVisitor();
					Object data = null;
					n.jjtAccept(gdv, data);
					st = gdv.getSymTable();
					model = (DefaultTableModel) jTableSemantics.getModel();
					for (; model.getRowCount() > 0;) {
						model.removeRow(0);
					}
					for (int i = 0; i < gdv.getDeclareMsg().size(); i += 4) {
						model.addRow(new Object[] { gdv.getDeclareMsg().get(i),
								gdv.getDeclareMsg().get(i + 1),
								gdv.getDeclareMsg().get(i + 2),
								gdv.getDeclareMsg().get(i + 3) });
					}
					if (gdv.getErrorMsg().size() > 0) {
						displayProblems(gdv.getErrorMsg());
					}
				}

			} catch (TokenMgrError e) {
				displayProblems(e);
			} catch (ParseException e) {
				displayProblems(e);
			} catch (Exception e) {
				displayProblems(e);
			}

			if (doAssembly) {
				AssemblyGenerator theA = new AssemblyGenerator();
				theA.root = (DefaultMutableTreeNode) jTreeSyntax.getModel()
						.getRoot();
				theA.codeGen(theA.root);
				// this is the output.
				String out;
				out = theA.result;

				JOptionPane.showMessageDialog(null, out,
						"IR Generation Preview",
						JOptionPane.INFORMATION_MESSAGE);

				String midFileName = "Mid.ll";
				String assemblyFileName = "Mid.s";
				writeStringToFile(out, midFileName);
				try {
					Process process = new ProcessBuilder("llc.exe",
							"-x86-asm-syntax=intel", midFileName).start();
					try {
						process.waitFor();
						readAssemblyFromFile(assemblyFileName);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

	void readAssemblyFromFile(String fileName) {
		File in = new File(fileName);
		try {
			jTextPaneAssembly.read(new FileReader(in.getAbsolutePath()), null);
		} catch (IOException ex) {
			System.out.println("problem accessing file" + in.getAbsolutePath());
		}
	}

	void writeStringToFile(String s, String fileName) {
		File out = new File(fileName);
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(out);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		OutputStreamWriter osw = new OutputStreamWriter(fos);
		try {
			osw.write(s);
			osw.flush();
			osw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	void displayProblems(Exception e) {
		DefaultTableModel model = (DefaultTableModel) jTableProblems.getModel();
		model.addRow(new Object[] { e.getMessage(), "", "", "Exception" });
	}

	void displayProblems(Error e) {
		DefaultTableModel model = (DefaultTableModel) jTableProblems.getModel();
		model.addRow(new Object[] { e.getMessage(), "", "", "Error" });
	}

	void displayProblems(ParseException e) {
		DefaultTableModel model = (DefaultTableModel) jTableProblems.getModel();
		model.addRow(new Object[] { e.getMessage(), ParseException.line,
				ParseException.column, "Parse Exception" });
	}

	void displayProblems(TokenMgrError e) {
		DefaultTableModel model = (DefaultTableModel) jTableProblems.getModel();
		model.addRow(new Object[] { e.getMessage(), TokenMgrError.line,
				TokenMgrError.column, "Token Error" });
	}

	void displayProblems(Vector<String> e) {
		DefaultTableModel model = (DefaultTableModel) jTableProblems.getModel();
		for (int i = 0; i < e.size(); i += 4) {
			model.addRow(new Object[] { e.get(i), e.get(i + 1), e.get(i + 2),
					e.get(i + 3) });
		}
	}

	boolean matchSymbol(String s) {
		if (s.matches("colon") || s.matches("semicolon") || s.matches("comma")
				|| s.matches("lbrace") || s.matches("rbrace")
				|| s.matches("dot") || s.matches("lparen")
				|| s.matches("rparen") || s.matches("lbracket")
				|| s.matches("rbracket") || s.matches("slice"))
			return true;
		else
			return false;
	}

	String getType(String s) {
		int colonPosition = s.indexOf(":");
		if (colonPosition != -1) {
			s = s.substring(0, colonPosition);
			s = s.replaceAll(" ", "");
		}
		return s;
	}

	String getCode(String s) {
		int colonPosition = s.indexOf(":");
		if (colonPosition != -1) {
			s = s.substring(colonPosition + 1, s.length());
			return s;
		} else {
			s = "";
		}
		for (; s.substring(0, 1).equals(" ");) {
			s = s.substring(1);
		}
		return s;
	}

	boolean hasChildrenWithType(DefaultMutableTreeNode node, String type) {
		for (int i = 0; i < node.getChildCount(); i++) {
			String thisString = node.getChildAt(i).toString();
			String thisType = getType(thisString);
			if (thisType.equals(type) || ("_" + thisType).equals(type)) {
				return true;
			}
		}
		return false;
	}

	public static void main(String args[]) {
		try {
			for (UIManager.LookAndFeelInfo info : UIManager
					.getInstalledLookAndFeels()) {
				if ("Nimbus".equals(info.getName())) {
					UIManager.setLookAndFeel(info.getClassName());
					break;
				}
			}
		} catch (ClassNotFoundException ex) {
			Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null,
					ex);
		} catch (InstantiationException ex) {
			Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null,
					ex);
		} catch (IllegalAccessException ex) {
			Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null,
					ex);
		} catch (UnsupportedLookAndFeelException ex) {
			Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null,
					ex);
		}

		EventQueue.invokeLater(new Runnable() {
			public void run() {
				new MainFrame().setVisible(true);
			}
		});
	}

	public static SymbolTable st = null;
	private Glowworm parser = new Glowworm(System.in);
	private JButton jButtonCompile;
	private JCheckBoxMenuItem jCheckBoxMenuItemAssembly;
	private JCheckBoxMenuItem jCheckBoxMenuItemLexical;
	private JCheckBoxMenuItem jCheckBoxMenuItemSemantics;
	private JCheckBoxMenuItem jCheckBoxMenuItemSyntax;
	private JFileChooser jFileChooser1;
	private JInternalFrame jInternalFrameAnalysis;
	private JInternalFrame jInternalFrameEditor;
	private JInternalFrame jInternalFrameProblem;
	private JMenuBar jMenuBar1;
	private JMenu jMenuCompile;
	private JMenu jMenuEdit;
	private JMenu jMenuFile;
	private JMenuItem jMenuItemCompile;
	private JMenuItem jMenuItemOpen;
	private JMenuItem jMenuItemRedo;
	private JMenuItem jMenuItemSaveAs;
	private JMenuItem jMenuItemUndo;
	private JMenu jMenuType;
	private JScrollPane jScrollPaneAssembly;
	private JScrollPane jScrollPaneEditor;
	private JScrollPane jScrollPaneLexical;
	private JScrollPane jScrollPaneProblems;
	private JScrollPane jScrollPaneSemantics;
	private JScrollPane jScrollPaneSyntax;
	private JSplitPane jSplitPaneHorizontal;
	private JSplitPane jSplitPaneVertical;
	private JTabbedPane jTabbedPaneAnalysis;
	private JTabbedPane jTabbedPaneEditor;
	private JTabbedPane jTabbedPaneProblems;
	private JTable jTableLexical;
	private JTable jTableProblems;
	private JTable jTableSemantics;
	private JTextPane jTextPaneAssembly;
	private JTextPane jTextPaneEditor;
	private JTree jTreeSyntax;
	private JToolBar jToolBar1;
}

class NumberedEditorKit extends StyledEditorKit {
	private static final long serialVersionUID = 1L;

	public ViewFactory getViewFactory() {
		return new NumberedViewFactory();
	}
}

class NumberedViewFactory implements ViewFactory {
	public View create(Element elem) {
		String kind = elem.getName();
		if (kind != null)
			if (kind.equals(AbstractDocument.ContentElementName)) {
				return new LabelView(elem);
			} else if (kind.equals(AbstractDocument.ParagraphElementName)) {
				// return new ParagraphView(elem);
				return new NumberedParagraphView(elem);
			} else if (kind.equals(AbstractDocument.SectionElementName)) {
				return new BoxView(elem, View.Y_AXIS);
			} else if (kind.equals(StyleConstants.ComponentElementName)) {
				return new ComponentView(elem);
			} else if (kind.equals(StyleConstants.IconElementName)) {
				return new IconView(elem);
			}
		// default to text display
		return new LabelView(elem);
	}
}

class NumberedParagraphView extends ParagraphView {
	public static short NUMBERS_WIDTH = 25;

	public NumberedParagraphView(Element e) {
		super(e);
		short top = 0;
		short left = 0;
		short bottom = 0;
		short right = 0;
		this.setInsets(top, left, bottom, right);
	}

	protected void setInsets(short top, short left, short bottom, short right) {
		super.setInsets(top, (short) (left + NUMBERS_WIDTH), bottom, right);
	}

	public void paintChild(Graphics g, Rectangle r, int n) {
		super.paintChild(g, r, n);
		int previousLineCount = getPreviousLineCount();
		int numberX = r.x - getLeftInset();
		int numberY = r.y + r.height - 5;
		g.drawString(Integer.toString(previousLineCount + n + 1), numberX,
				numberY);
	}

	public int getPreviousLineCount() {
		int lineCount = 0;
		View parent = this.getParent();
		int count = parent.getViewCount();
		for (int i = 0; i < count; i++) {
			if (parent.getView(i) == this) {
				break;
			} else {
				lineCount += parent.getView(i).getViewCount();
			}
		}
		return lineCount;
	}
}
